using System;
using System.Collections.Generic;
using System.ComponentModel;

using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CodePlex.SpaceBlock;
using CodePlex.SpaceBlock.FS;
using System.Threading;
using CodePlex.Resourceful.Amazon.S3;

namespace CodePlex.SpaceBlock.UI.Controls.Explore
{
    public partial class ACLEditorForm : CodePlex.SpaceBlock.UI.Controls.BaseForm
    {
        public ACLEditorForm(IFileSystem fs, List<Path> paths)
        {
            InitializeComponent();

            if (paths.Count == 0)
            {
                this.Dispose();
            }

            string text = "(multiple items)";

            if (paths.Count == 1)
            {
                text = paths[0].Name;
            }

            this.Text = string.Format("Edit ACL for '{0}'", text);

            _okButton.Enabled = false;

            this.Cursor = Cursors.WaitCursor;



            ISupportsACL aclSupport = fs as ISupportsACL;



            this.InBackground(delegate
            {
                ACL acl = aclSupport.GetACL(paths[0]);
                IEnumerable<ACLPrincipal> principals = aclSupport.GetPrincipals();
                IEnumerable<string> permissions = aclSupport.GetPermissions();

                this.InDisplay(delegate
                {
                    this.Setup(fs, aclSupport, paths, acl, principals, permissions);
                    this.Cursor = Cursors.Default;

                });

            });

        }


        private void Setup(IFileSystem fs, ISupportsACL aclSupport, IEnumerable<Path> paths, ACL acl, IEnumerable<ACLPrincipal> principals, IEnumerable<string> permissions)
        {
            ACLControl control = new ACLControl(null);

            control.ACL = acl;

            UIUtils.FillWith(_aclHolder, control);

            DataGridView2 gridPrincipals = new DataGridView2();
            DataGridViewColumn col = gridPrincipals.AddColumnText("Principal", 100);
            col.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

            foreach (ACLPrincipal principal in principals)
            {
                string hint = UIConstants.ImageHints.User;
                if (principal.IsGroup)
                {
                    hint = UIConstants.ImageHints.UserGroup;
                }
                gridPrincipals.AddRow(principal, UIManager.Instance.GetSmallImage(hint), principal.Name);


            }

            UIUtils.FillWith(_principalHolder, gridPrincipals);

            DataGridView2 gridPermissions = new DataGridView2();
            col = gridPermissions.AddColumnText("Permission", 100);
            col.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

            foreach (string permission in permissions)
            {
                gridPermissions.AddRow(permission, UIManager.Instance.GetSmallImage(UIConstants.ImageHints.User), permission);
            }

            UIUtils.FillWith(_permissionHolder, gridPermissions);




            ActionManager actions = new ActionManager(this, null, _contextMenu, null);

            Action<ACLPrincipal> addPrincipal = delegate(ACLPrincipal principal)
            {
                gridPrincipals.AddRow(principal, UIManager.Instance.GetSmallImage(UIConstants.ImageHints.User), principal.Name);
            };

            actions.NewAction("FromEmailAddress", "...from Email Address", 0, Keys.None, delegate
            {
                InputboxForm form = new InputboxForm();

                form.Icon = this.Icon;

                form.Title = Properties.Messages.ACLFromEmailAddress_Title;
                form.Prompt = "Email:";
                form.Description = Properties.Messages.ACLFromEmailAddress_Description;

                form.Height += 30;


                if (form.ShowDialog(this) == DialogResult.OK)
                {
                    if (form.Value.Trim().Length == 0)
                    {
                        return;
                    }

                    AmazonCustomerByEmail principal = new AmazonCustomerByEmail(form.Value.Trim());

                    addPrincipal(principal);
                }

            });



            actions.NewAction("FromUserID", "...from User ID", 0, Keys.None, delegate
           {
               InputboxForm form = new InputboxForm();

               form.Icon = this.Icon;

               form.Title = Properties.Messages.ACLFromUserID_Title;
               form.Prompt = "User ID:";
               form.Description = Properties.Messages.ACLFromUserID_Description;

               if (form.ShowDialog(this) == DialogResult.OK)
               {
                   if (form.Value.Trim().Length == 0)
                   {
                       return;
                   }
                   ACLPrincipal principal = new ACLPrincipal(form.Value.Trim(), form.Value.Trim(), false);

                   addPrincipal(principal);

               }

           });

            _newPrincipalButton.Click += delegate
           {
               _contextMenu.Show(_newPrincipalButton, new Point(0, _newPrincipalButton.Height));
           };


            _addButton.Click += delegate
            {

                ACLPrincipal principal = gridPrincipals.SelectedRows[0].Tag as ACLPrincipal;
                string permission = gridPermissions.SelectedRows[0].Tag as string;

                acl.Add(principal, permission);

                control.ACL = acl;

                _okButton.Enabled = true;
            };


            _removeButton.Click += delegate
            {
                ACLPrincipal principal = control.SelectedPrincipal;
                string permission = control.SelectedPermission;

                if (principal == null || permission == null)
                {
                    return;
                }


                acl.Remove(principal, permission);
                control.ACL = acl;
                _okButton.Enabled = true;

            };



            // ok
            this.SetupDialogWork(_cancelButton, _okButton, delegate
            {
                Action<Path> setACL = null;

                setACL = delegate(Path path)
                 {
                     aclSupport.SetACL(path, acl);

                     if (path.IsFolder)
                     {
                         foreach (IPathItem child in fs.GetItems(path))
                         {
                             setACL(child.Path);
                         }
                     }
                 };

                foreach (Path path in paths)
                {
                    setACL(path);
                }

                return true;
            });
            

            _okButton.Enabled = true;

        }

    }
}

